/**
 * 
 */
package eMdP.classesBasiques;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.URL;
import java.util.logging.Logger;

import com.jme.bounding.BoundingBox;
import com.jme.image.Texture;
import com.jme.math.FastMath;
import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.Node;
import com.jme.scene.Spatial;
import com.jme.scene.shape.Box;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.util.TextureManager;
import com.jme.util.export.binary.BinaryImporter;
import com.jmex.model.converters.MaxToJme;
import com.jmex.physics.StaticPhysicsNode;

import eMdP.estats.Partida;
import eMdP.gestors.GestorModels;

/**
 * @author redribbon
 *
 */
public class Furgoneta extends Node {
	private static final long serialVersionUID = 1L;
	private static final Logger logger = Logger.getLogger(Partida.class.getName());
	
	private boolean horitzontal;
	private int carregaments;
	private Vector3f puntArribada;
	private Vector3f puntFinal;
	
	private Spatial model;
	
	private StaticPhysicsNode nodeEstatic;
	
	//Variable per saber quant de temps porta el jugador sense poder-se moure
	private float tempsBlocat;
	private float tempsInici;
	
	/**
	 * @param name
	 */
	public Furgoneta(String nom, StaticPhysicsNode nodeEstatic) {
		super(nom);
		
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		
		setPuntArribada(new Vector3f(0,0,10));
		
		
		Box model = new Box("ModelFurgo",new Vector3f(0,0,0),18,12,8);
		model.setModelBound(new BoundingBox());
		model.updateModelBound();  
		// Girem 90º
		//model.getLocalRotation().fromAngleAxis(FastMath.PI/2, new Vector3f(0, 1, 0));
		
		setModel(model);
		
		this.carregaments = 3;
		
		this.horitzontal=true;
		
		this.setPuntArribada(new Vector3f(0,1,9f));
		this.setPuntFinal(new Vector3f(-15,1,9f));
		
		nodeEstatic.generatePhysicsGeometry();
		this.attachChild(nodeEstatic);
		
		this.tempsBlocat = 0;
    	this.tempsInici = 0;
	}
	
	/**
	 * @param name
	 */
	public Furgoneta(String nom, StaticPhysicsNode nodeEstatic,Vector3f puntArribada, Vector3f puntFinal, boolean portaPaquets) {
		super(nom);
		
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		
		
		
		Box model = new Box("ModelFurgo",new Vector3f(0,14,0),18f,14f,8);
		model.setModelBound(new BoundingBox());
		model.updateModelBound();
		// Girem 90º
		//model.getLocalRotation().fromAngleAxis(FastMath.HALF_PI, new Vector3f(0, 1, 0));
		setModel(model);
		//setModel(GestorModels.get3DS("eMdP/altresModels/furgo.3ds"));
		//this.model.getLocalRotation().fromAngleAxis(FastMath.HALF_PI, new Vector3f(0,1,0));
		if(portaPaquets)
			this.carregaments = 1;
		else
			this.carregaments = 1;
		
		this.horitzontal=true;
		
		this.setPuntArribada(puntArribada);
		this.setPuntFinal(puntFinal);
		
		nodeEstatic.generatePhysicsGeometry();
		this.attachChild(nodeEstatic);
		
		this.tempsBlocat = 0;
    	this.tempsInici = 0;
	}
	
	/**
	 * @param name
	 */
	public Furgoneta(String nom, String direccioModel, StaticPhysicsNode nodeEstatic) {
		super(nom);
		
		setNodeEstatic(nodeEstatic);
		this.nodeEstatic.setName("nodeEstatic"+nom);
		
		setPuntArribada(new Vector3f(0,0,10));
		
		
		/*Box model = new Box("ModelFurgo",new Vector3f(0,0,0),0.75f,1,1);
		model.setModelBound(new BoundingBox());
		model.updateModelBound();
		*/
		// Girem 45º
		
		
		Spatial model = carregarModel(direccioModel);
		model.getLocalRotation().fromAngleAxis(FastMath.PI/2, new Vector3f(0, 1, 0));
		
		setModel(model);
		
		this.carregaments = 1;
		
		this.horitzontal=true;
		
		this.setPuntArribada(new Vector3f(0,1,11f));
		this.setPuntFinal(new Vector3f(-15,1,11f));
		
		nodeEstatic.generatePhysicsGeometry();
		this.attachChild(nodeEstatic);
		
		this.tempsBlocat = 0;
    	this.tempsInici = 0;
	}
	
	/**
	 * @param name
	 */
	public Furgoneta(String name,Spatial model, int carregaments, boolean horitzontal, StaticPhysicsNode nodeEstatic) {
		super(name);
		this.carregaments = carregaments;
		setNodeEstatic(nodeEstatic);
		setModel(model);
		
		this.horitzontal = horitzontal;
		
		this.nodeEstatic.generatePhysicsGeometry();
		
		this.tempsBlocat = 0;
    	this.tempsInici = 0;
	}

	/**
	 * @return the carregaments
	 */
	public int getCarregaments() {
		return carregaments;
	}

	/**
	 * @param carregaments the carregaments to set
	 */
	public void setCarregaments(int carregaments) {
		System.out.println("Carreguem la furgo");
		this.carregaments = carregaments;
	}

	/**
	 * @return the model
	 */
	public Spatial getModel() {
		return model;
	}

	/**
	 * @param model the model to set
	 */
	public void setModel(Spatial model) {
		this.model = model;
		this.getNodeEstatic().attachChild(model);
		setTextura();
	}

	/**
	 * @return the nodeEstatic
	 */
	public StaticPhysicsNode getNodeEstatic() {
		return nodeEstatic;
	}

	/**
	 * @param nodeEstatic the nodeEstatic to set
	 */
	public void setNodeEstatic(StaticPhysicsNode nodeEstatic) {
		this.nodeEstatic = nodeEstatic;
	}

	/**
	 * @return the horitzontal
	 */
	public boolean isHoritzontal() {
		return horitzontal;
	}

	/**
	 * @param horitzontal the horitzontal to set
	 */
	public void setHoritzontal(boolean horitzontal) {
		this.horitzontal = horitzontal;
	}
	
	/**
	 * @return the puntArribada
	 */
	public Vector3f getPuntArribada() {
		return puntArribada;
	}

	/**
	 * @param puntArribada the puntArribada to set
	 */
	public void setPuntArribada(Vector3f puntArribada) {
		this.puntArribada = puntArribada;
	}
	
	/**
	 * @return the puntFinal
	 */
	public Vector3f getPuntFinal() {
		return puntFinal;
	}

	/**
	 * @param puntFinal the puntFinal to set
	 */
	public void setPuntFinal(Vector3f puntFinal) {
		this.puntFinal = puntFinal;
	}
	
	
	
	/* ------------------------ Fi Getter's & Setter's ---------------------------- */

	/**
	 * 
	 */
	public void actualitzar(float tIS){
		if(this.carregaments > 0 && (this.getLocalTranslation().distance(getPuntArribada())>1)){
			if(!estaBloquejat(tIS))this.anarA(0,tIS); //Va a Descarregar
		}else if(this.carregaments <1 && (this.getLocalTranslation().distance(getPuntFinal())>1)){
			if(!estaBloquejat(tIS))this.anarA(1,tIS); //Va a Carregar
		}else if(this.carregaments==0 && (this.getLocalTranslation().distance(getPuntFinal())<=1)){
			this.bloquejar(tIS, 7);
			setCarregaments(1); //Carreguem la furgoneta, perqué al cap de 5 segons torni a anar cap al terreny de joc
		}
	}
	
	/**
	 * 
	 */
	private void anarA(int lloc, float tIS){
		/* lloc -> 0, anar a descarregar. lloc -> 1 anar a carregar */
		Vector3f loc = new Vector3f(this.getLocalTranslation());
		float x = 0.5f;
		if(this.puntArribada.getX()-this.puntFinal.getX() < 0 && lloc==0) x= x*(-1);
		else if(this.puntArribada.getX()-this.puntFinal.getX() > 0 && lloc==1)	x= x*(-1);
		loc.addLocal(x, 0, 0);
		this.setLocalTranslation(loc);
	}
	
	/**
	 * Métode per bloquejar a un Personatge perqué no es pugui moure
	 * @param tempsI Instant del temps en que ha estat blocat
	 * @param tempsT Els segons que ha estat blocat
	 */
	public void bloquejar(float tempsI, float tempsT){
		this.tempsInici = tempsI;
		this.tempsBlocat = tempsT;
	}
	
	
	/**
	 * Métode per saber si una Furgo es pot moure o no.
	 * @param temps Temps actual
	 */
	public boolean estaBloquejat(float temps){
		
		boolean retorn=false;
		if(this.tempsBlocat>0){
			if(temps>this.tempsBlocat+this.tempsInici){
				retorn=false;this.tempsBlocat=0;
			}else{
				retorn = true;
			}
		}
		return retorn;
	}
	
	
	/**
	 * 
	 */
	public void unCarregamentFet(float tIS){
		//logger.info("FURGONETA::Descarreguem un carregament de 4 Paquets");
		this.carregaments--;
		bloquejar(tIS,6);
	}
	
	/**
	 * 
	 */
	public boolean potDescarregar(){
		return (this.getLocalTranslation().distance(puntArribada)<=1 && this.getCarregaments()>0);
	}
	
	/**
	 * 
	 * @param direccio
	 * @return
	 */
	
	private Node carregarModel(String direccio){
    	Node nodeBustia = new Node("Furgoneta");
    	
    	URL modelToLoad = Personatge.class.getClassLoader().getResource(direccio);
		
    	try {
            MaxToJme C1 = new MaxToJme();
            ByteArrayOutputStream BO = new ByteArrayOutputStream();
            C1.convert(new BufferedInputStream(modelToLoad.openStream()), BO);
            nodeBustia = (Node)BinaryImporter.getInstance().load(new ByteArrayInputStream(BO.toByteArray()));
            
            Quaternion temp = new Quaternion();
            temp.fromAngleAxis(FastMath.PI / 2, new Vector3f(-1, 0, 0));
            nodeBustia.setLocalRotation(temp);
            //logger.info("Bustia carregada amb Éxit");
        } catch (IOException e) {
            //logger.log(Level.SEVERE, "Failed to load Max file", e);
        }
       //nodeBustia.setLocalScale(2f);
       
       nodeBustia.setModelBound(new BoundingBox());
       nodeBustia.updateModelBound();
       //nodeBustia.getLocalTranslation().addLocal(0, 1, 0);
       nodeBustia.getLocalTranslation().set(15, 1, 10.75f);
        return nodeBustia;
    
	}
	
	private void setTextura()
	{
		String fitxerTextura = "eMdP/altresModels/TEX/FURGO.TGA";
		DisplaySystem display = DisplaySystem.getDisplaySystem();
    	//System.out.println(fitxerTextura);
    	TextureState ts = display.getRenderer().createTextureState();
		ts.setEnabled(true);
		ts.setTexture(
		TextureManager.loadTexture(
			GestorModels.class.getClassLoader().getResource(fitxerTextura),
			Texture.MinificationFilter.Trilinear,
			Texture.MagnificationFilter.Bilinear)
		);
		this.setRenderState(ts);
	}
}
